package com.cizzy.video;

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.cizzy.video.recommend.VideoRecommendation;
import io.micrometer.core.instrument.MeterRegistry;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;

import static com.cizzy.video.config.CizzyFinal.*;

@MapperScan("com.cizzy.video.mapper")
@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
@EnableAspectJAutoProxy
public class VideoServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(VideoServerApplication.class, args);
        initFlowQpsRule();
        initCircuitBreakerRule();
        // 开启推荐算法
        if(RECOMMENDATION_OPEN) {
            Thread recommendThread = new Thread(new VideoRecommendation());
            recommendThread.start();
        }
    }

    /**
     * 初始化限流器规则
     */
    private static void initFlowQpsRule() {
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule("video");
        // set limit qps to 2
        rule.setCount(QPS_LIMIT);
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule.setLimitApp("default");
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }

    /**
     * 初始化断路器规则
     */
    public static void initCircuitBreakerRule() {
        List<DegradeRule> rules = new ArrayList<>();
        DegradeRule rule = new DegradeRule("video");
        // 设置熔断降级阈值为 5 秒内的平均响应时间
        rule.setCount(DEGRADE_LIMIT);
        // 设置熔断降级的策略，这里选择慢调用比例
        rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
        rule.setTimeWindow(DEGRATE_TIME_WINDOW); // 统计时间窗口为 10 秒
        rule.setMinRequestAmount(MIN_DEGRADE_NUM); // 最小请求数
        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }

    @Bean
    RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
